package com.randi.file.service.impl;

import com.randi.common.constant.CacheConstants;
import com.randi.common.enums.ResultCode;
import com.randi.common.exception.ServiceException;
import com.randi.common.utils.RedisUtil;
import com.randi.common.utils.StringUtils;
import com.randi.common.utils.uuid.IdUtils;
import com.randi.file.entity.SysFile;
import com.randi.file.mapper.SysFileMapper;
import com.randi.file.service.ISysFileService;
import com.randi.file.utils.SysFileUtils;
import com.randi.file.utils.UploadFileUtils;
import com.randi.file.utils.UploadSliceUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author ziye
 */
@Service
public class SysFileServiceImpl implements ISysFileService {

    @Resource
    private SysFileMapper sysFileMapper;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 查询业务列表
     *
     * @param sysFile sysFile
     * @return 业务集合
     */
    @Override
    public List<SysFile> selectSysFileList(SysFile sysFile) {
        sysFile.setDeleted(0);
        return sysFileMapper.selectSysFileList(sysFile);
    }

    /**
     * 查看详情
     *
     * @return 业务集合
     */
    @Override
    public SysFile selectSysFileById(Long fileId) {
        SysFile sysFile = new SysFile();
        sysFile.setFileId(fileId);
        sysFile.setDeleted(0);
        return sysFileMapper.selectSysFileList(sysFile).stream().findFirst().orElse(null);
    }

    /**
     * 根据文件哈希获取文件对象
     *
     * @param fileHash 文件哈希
     * @return 文件对象
     */
    @Override
    public SysFile selectSysFileByHash(String fileHash) {
        SysFile sysFile = new SysFile();
        sysFile.setFileHash(fileHash);
        return sysFileMapper.selectSysFileList(sysFile).stream().findFirst().orElse(null);
    }

    /**
     * 插入数据
     *
     * @param sysFile sysFile
     * @return 结果
     */
    @Override
    public int insertSysFile(SysFile sysFile) {
        sysFile.setCreateTime(new Date());
        return sysFileMapper.insert(sysFile);
    }

    /**
     * 更新数据
     *
     * @param sysFile SysFile
     * @return 结果
     */
    @Override
    public int updateSysFile(SysFile sysFile) {
        return sysFileMapper.updateById(sysFile);
    }

    /**
     * 恢复删除文件数据
     *
     * @param fileHash 文件哈希
     * @return 状态
     */
    @Override
    public int recoverSysFileDeleted(String fileHash) {
        SysFile sysFile = new SysFile();
        sysFile.setFileHash(fileHash);
        sysFile.setDeleted(1);
        int size = sysFileMapper.selectSysFileList(sysFile).size();
        if (size != 0) {
            return sysFileMapper.recoverSysFileDeleted(fileHash);
        }
        return 1;
    }

    /**
     * 删除数据
     *
     * @param fileId fileId
     * @return 结果
     */
    @Override
    public int deleteSysFile(Long fileId) {
        SysFile sysFile = new SysFile();
        sysFile.setFileId(fileId);
        sysFile.setDeleted(1);
        return sysFileMapper.updateById(sysFile);
    }

    /**
     * 批量删除数据
     *
     * @param fileIds fileIds
     * @return status
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteBatchSysFile(List<Long> fileIds) {
        fileIds.forEach(this::deleteSysFile);
        return 1;
    }

    /**
     * 创建文件下载链接
     *
     * @param fileId 文件ID
     * @return 下载链接
     */
    @Override
    public String createDownloadUrl(Long fileId) {
        SysFile sysFile = this.selectSysFileById(fileId);
        if (sysFile == null) {
            return null;
        }
        String fileHash = sysFile.getFileHash();
        boolean fileExist = UploadSliceUtils.hasBeenFileUploaded(fileHash);
        if (!fileExist) {
            throw new ServiceException(ResultCode.FILE_DOWNLOAD_FAIL_NOT_EXIST);
        }
        String cacheKey = IdUtils.fastSimpleUUID();
        redisUtil.setCache(CacheConstants.FILE_DOWNLOAD_KEY + cacheKey, sysFile, 2 * 3600, TimeUnit.MINUTES);
        return cacheKey;
    }

    /**
     * 文件下载
     *
     * @param response response
     * @param taskId   任务ID
     */
    @Override
    public void fileDownload(HttpServletResponse response, String taskId) {
        SysFile sysFile = redisUtil.getCache(CacheConstants.FILE_DOWNLOAD_KEY + taskId);
        String pathname = UploadSliceUtils.getSaveFilePath(sysFile.getFileHash());
        UploadSliceUtils.download(response, pathname, sysFile.getFileNamePro());
    }

    /**
     * 预览文件
     *
     * @param response HttpServletResponse
     * @param pathName 文件路径
     * @param fileName 文件名称
     */
    @Override
    public void filePreview(HttpServletResponse response, String pathName, String fileName) {
        UploadFileUtils.preview(response, pathName, fileName);
    }

}
